﻿using System;

namespace PoolKit
{
    /// <summary>
    /// Functional shortcut for creating a <see cref="ReusePreparationStrategy{TResource}"/>
    /// </summary>
    /// <typeparam name="TResource">Type of resource the strategy can handle</typeparam>
    public class ReusePreparationFunction<TResource> : ReusePreparationStrategy<TResource>
    {
        private readonly Action<TResource> _reusePreparationAction;
        private readonly ThreadingContract _threadingContract;

        /// <summary>
        /// Creates a reuse preparation strategy from the provided function
        /// </summary>
        /// <param name="reusePreparationAction">Function that defines the strategy</param>
        /// <param name="threadingContract">Specifies the threading contract exposed by the strategy (whether it is safe to call into the strategy simultaneously from several threads).</param>
        /// <exception cref="ArgumentNullException"></exception>
        public ReusePreparationFunction(Action<TResource> reusePreparationAction, ThreadingContract threadingContract)
        {
            if (reusePreparationAction == null) throw new ArgumentNullException("reusePreparationAction");

            _reusePreparationAction = reusePreparationAction;
            _threadingContract = threadingContract;
        }

        /// <summary>
        /// True, if it is safe to call into the strategy simultaneously from several threads; False - otherwise.
        /// </summary>
        public override ThreadingContract ThreadingContract
        {
            get
            {
                return _threadingContract;
            }
        }

        /// <summary>
        /// Prepares given resource for reuse - usually by wiping its state clean.
        /// </summary>
        /// <param name="resourceToBeReused">Resource to prepare for reuse</param>
        public override void PrepareForReuse(TResource resourceToBeReused)
        {
            _reusePreparationAction.Invoke(resourceToBeReused);
        }
    }
}